package com.ywk.log.controller;

import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Map;

/**
 * 参考链接：https://www.jianshu.com/p/406a531abdd4
 * （扩展：搭建Skywalking分布式链路追踪与监控，并接入Java项目的教程：
 * https://blog.csdn.net/sinat_27933301/article/details/122912185）
 *
 * spring集成日志服务：添加logback.xml文件即可
 *
 * 日志组件选择：不要直接使用log4j或logback打印日志，而是使用Slf4j日志门面框架，其本身不会打日志，而是需要结合实际的日志系统。
 * 在项目中使用了 slf4j 记录日志，并且绑定了 log4j（即导入相应的依赖），则日志会以 log4j 的风格输出；
 * 后期需要改为以 logback 的风格输出日志，只需要将 log4j 替换成 logback 即可，不用修改项目中的上层代码
 *
 * @Author zbh
 * @Date 2023/4/25
 */
@Controller
@RequestMapping("/logDemo")
@Slf4j
public class LogDemoController {

    @RequestMapping("/log1")
    @ResponseBody
    public void log1(){

        log.info("log1");
        getOrder();
    }
    /**
     *
     * 配置文件设置打印级别为info，只会打印info以上级别的日志：error，warn和info
     */
    public void logLevel() {
        //CTA打日志标准
        log.error("这个错误很严重﹐程序阻断了﹐[授记监控﹐发到报警");
        log.warn("这个错误不应该出来啊﹐程序可以继续往下走﹐但是太没面子了");
        log.info("没啥事，就是想打个日志");
        log.debug("作为一个经常写BUG的程序员，开发联调阶段，多打点日志很合理");
        log.trace("从来没用过,他们说是为了追踪");
        //正确打印debug（现在不推荐）
        if (log.isDebugEnabled()) {
            log.debug("别嫌麻烦，不想被开除最好这样做");
        }
        //打印debug改成懒加载
//        log.debug("xxxxx, {}", () -> new Object());
        try {
            //主流程业务
            getOrder();
        } catch (Exception e) {
            log.error("order error", e);
        }
        try {
            //不影响主流程
            getRevenue();
        } catch (Exception e) {
            log.warn("revenue error: ", e);

        }
    }

    /**
     * 注：
     * 1.使用{} 占位符（效率高），而不是字符串拼接
     * 2.判断debug模式是否开启
     *
     * @param request
     * @return
     */
    @PostMapping("/log")
    public Object log(@RequestBody Map<String,Object> request) {
        //接口调用前后
        log.info("log( called with parameters => [request = {}]", new Gson().toJson(request));
        Object resp = new Object();
        Boolean isVip = Boolean.TRUE;
        //条件分支：if/switch
        if (isVip) {
            log.info("vip biz");
        } else {
            log.info("not vip biz");
        }
        //调用三方接口前后
        String param="";
        log.info("callRemote start request:{}",param);
        Object remote = callRemote(param);
        log.info("callRemote response:{}", remote);

        //try-catch代码块
        try {
            getOrder();
        } catch (Exception e) {
            // e.printStackTrace();//别再用了（产生的字符串信息是堆栈信息，可能会很多）
            log.error("get order error", e);
        }

        log.info("log() returned: {}",resp);
        return resp;
    }

    /**
     * 一个不能出错的方法
     */
    private void getOrder() {
        log.info("getOrder");
    }

    /**
     * 不影响主流程业务
     */
    private void getRevenue() {
    }

    private Object callRemote(String param) {
        return null;
    }
}